perm filename WALDSK.SAI[SYS,HE] blob
sn#055854 filedate 1973-07-30 generic text, type T, neo UTF8
00100 BEGIN "WALEYE"
00200
00300 COMMENT This is a corner finding program using the Hueckel
00400 edge_operator. It will find lines, corners
00500 with 2 sides and physical corners with 3 sides;
00600
00700
00800 REQUIRE "{ } { }" DELIMITERS;
00900 REQUIRE "PREAMB.SAI[SYS,HE]" SOURCE_FILE;
01000 REQUIRE "HELIB[1,3]" LIBRARY;
01100 REQUIRE "EDGE.HDR[VIS,WAP]" SOURCE_FILE;
01200 REQUIRE "SAITRG[SYS,BGB]" SOURCE_FILE;
01300
01400 DEFINE DINT="2."; COMMENT THIS IS USED AS RADIUS IN WHICH WE
01500 CONSIDER NEW VERTEX TO BE THE SAME AS ONE
01600 FOUND PREVIOUSLY;
01700
01800
01900 DEFINE SINDIR="12", COSDIR="13", SINTHETA="9", COSTHETA="10";
02000
02100
02200 SHORT REAL SCAL;
02300 SHORT INTEGER REQUEST,EXFLAG,DUMMY,MINI,MAXI,DE,INTS,LINS;
02400 SHORT INTEGER ARRAY STOR[1:25],HIST[-1:16];
02500 SHORT INTEGER EXT,PPN,FAIL,BRK,NCORNERS,CORNERNUMBER;
02600 BOOLEAN EXT_LINE;
02700 STRING PIC;
02800 INTEGER ARRAY ITEMVAR TVPIC;
02900
03000
03100 EXTERNAL PROCEDURE PICINI(INTEGER C,F,E,P,G;INTEGER ARRAY S);
03200 EXTERNAL PROCEDURE PICRD(INTEGER FAIL; INTEGER ARRAY S);
03300 EXTERNAL INTEGER PROCEDURE GIOWD(INTEGER ARRAY BUF);
03400 EXTERNAL PROCEDURE INTPNT;
03500 EXTERNAL INTEGER PROCEDURE GETPNT(INTEGER X,Y);
03600 EXTERNAL INTEGER TVWORD, LSIDE,RSIDE,FLINE,LLINE,BITS;
03700
03800 comment to run without PREAMB the following declarations should be added here;
03900 comment BOOLEAN DIS_EYE,DEB_EYE,TYP_EYE;
04000 comment REAL ARRAY DIR_EYE[0:10,1:8];
04100 comment INTEGER ARRAY LOOK_AT[1:8];
04200
04300 DEFINE ⊃="COMMENT", DPYBUF="BUF", INTEGER_ARRAY="INTEGER ARRAY";
04400 DEFINE CRLF="'15&'12", ACRLF="&'15&'12"; DEFINE YES="INCHWL=""Y""";
04500 DEFINE PRINT(FOO)={OUTSTR(" FOO="&CVG(FOO)ACRLF);};
04600 DEFINE WAIT="IF DEB_EYE THEN BEGIN OUTSTR(""...TYPE Y TO CONTINUE...""ACRLF);
04700 IF INCHWL=""Y"" THEN; END";
00100 SHORT INTEGER X, Y,DX,DY, NHIGH,NLINES,NVERTEX,NDRES;
00200 SHORT INTEGER X_WIDTH,Y_WIDTH;
00300 SHORT INTEGER EDGE_LIMIT, LT_LIMIT, LINE_LIMIT,VERT_LIMIT;
00400 SHORT REAL NDTH,NDC,NDS,NDCHI,NDRADIUS,NDGAP;
00500 SHORT REAL NDANG,NDACC, DELTA_X,DELTA_Y,DXY;
00600 BOOLEAN CAL_COMP; ⊃ IT TRUE THEN MAKE CALCOMP PLOTS OF SOME DISPLAYS;
00700 BOOLEAN CAL2_COMP; ⊃ IT TRUE THEN MAKE CALCOMP PLOTS OF SOME DISPLAYS.
00800 This is used for displaying SET_FOR_SCAN edge points;
00900
01000 PROCEDURE INIT;
01100 BEGIN
01200 X←0;Y←0;DX←2;DY←2;
01300
01400
01500 ⊃ Line finder variables;
01600 NDTH←0.23; ⊃ THIS SETS HALF THE THETA WINDOW FOR EDGE_POINTS FORMING A LINE;
01700 NDC←30.0; ⊃ THIS SETS HALF THE C WINDOW FOR EDGE_POINTS FORMING A LINE;
01800 NDRES←2; ⊃ THIS SETS SPACING IN THE RESIDUAL HISTOGRAM.
01900 LARGER NUMBER MADE IT EASIER TO FIND A LINE;
02000 NDS←4.; ⊃ THIS SETS THE MINIMUM GAP LENGTH FOR WHICH 2 EDGE_POINTS
02100 WILL BE JOINED TO FORM A SOLID LINE;
02200 NDCHI←1.0; ⊃ THIS SETS THE MAXIMUM ALLOWABLE CHI-VALUE
02300 FOR A SET OF POINTS TO BE CONSIDERED A LINE;
02400 NDRADIUS←6; ⊃ RADIUS OF CIRCLE USED TO EXTEND END OF LINES;
02500 NDGAP←0.5; ⊃ MAXIMUM PERCENTAGE OF LENGTH FOR GAP BETWEEN EDGE POINTS;
02600 NDANG←0.15; ⊃ THIS DETERMINES THE ACCEPTABLE DIFFERENCE IN
02700 FOR TWO LINES TO BE MADE INTO ONE;
02800 NDACC←.75; ⊃ THIS SETS THE ACCEPTABLE PERPENDICULAR DISTANCE BETWEEN
02900 LINES AND VERTEX CENTER FOR A THREE LINE VERTEX;
03000 NHIGH←4; ⊃ IF THE NUMBER OF GOOD EDGE POINTS
03100 IS ≥ NHIGH + 1 THEN A LINE WILL BE FOUND EVENUTALLY;
03200
03300 CAL_COMP←CAL2_COMP←0; ⊃ Used for Calcomp plots;
03400
03500 ⊃ Window variables;
03600 X_WIDTH←40; ⊃ INITIAL WINDOW WIDTH;
03700 Y_WIDTH←30; ⊃ INITIAL WINDOW HEIGHT;
03800 DELTA_X←X_WIDTH/2.-6;
03900 DELTA_Y←Y_WIDTH/2.-6;
04000
04100
04200 ⊃ Array limits;
04300 EDGE_LIMIT←1200;
04400 LT_LIMIT←600;
04500 LINE_LIMIT← 15;
04600 VERT_LIMIT← 15;
04700
04800
04900 END;
05000
05100 REQUIRE INIT INITIALIZATION;
00100
00200
00300
00350 BOOLEAN WANT_ALL; ⊃ If true the find all corners. Otherwise find
00375 one corner and stop;
00400 BOOLEAN DISP_HIST; ⊃ IF TRUE THEN DISPLAY HISTOGRAMS;
00500 BOOLEAN DISP_POINTS; ⊃ IF TRUE THEN DISPLAY THETA-C POINTS;
00550 BOOLEAN DISP_VERT; ⊃ If true then make extra vertes displays;
00600 SHORT INTEGER EDGE_COUNT,EDGE_INDEX,LEDGE_INDEX;
00700 DEFINE EDGE_BLSIZE = "4", EBS = "4",EDGE_X="0", EDGE_Y="1",
00800 EDGE_TH="2", EDGE_C="3";
00900 DEFINE PI1 = "3.1415927", SQ2 = "1.414214";
01000 DEFINE PIT2 = "6.283185", PIO2 = "1.570796", PI6=".523595";
01100 DEFINE BUF_LIMIT="5000", BUF2_LIMIT="2", HUMP_LIMIT = "50";
01200
01300
01400 SHORT INTEGER X1,Y1,X2,Y2; ⊃ Window variables;
02100
02200 REQUIRE "DPY2.HDR[VIS,WAP]" SOURCE_FILE;
00100
00200
00300 PROCEDURE INPUT;
00400 BEGIN "IN"
00500 ⊃ THIS PROCEDURE READS IN A PICTURE FROM THE DISK;
00600 LABEL L1;
00700 NLINES←NVERTEX←0;
00800 L1: OUTSTR(" INPUT FILE = "ACRLF);
00900 PIC ← INCHWL;
01000 PICINI(1,CVFIL(PIC,EXT,PPN),EXT,PPN,FAIL,STOR);
01100 IF FAIL∨¬STOR[1] THEN GO TO L1;
01200 STOR[2] ← 0;
01300 ARRBLT(STOR[3], STOR[2], 23);
01400 BEGIN
01500 INTEGER ARRAY TV[1:STOR[1]];
01600 IF TVPIC ≠ EVERY THEN GLOBAL DELETE(TVPIC);
01700 TVPIC ← GLOBAL NEW(TV);
01800 END;
01900 TVWORD ← GIOWD(GLOBAL DATUM(TVPIC));
02000 STOR[1] ← TVWORD +1;
02100 PICRD(FAIL,STOR);
02200 RELEASE(1);
02300 INTPNT; ⊃ THIS PROC. MUST BE CALLED SO THAT GETPNT CAN GET
02400 INTENSITY VALUES;
02500 EJINIT; ⊃ THIS INITIALIZES EDGED OPERATOR;
02600 DIS_EYE ← -1;
02700 DEB_EYE ← -1;
02800 EXFLAG ←1;
02900 LOOK_AT[6] ←0;
03000 LOOK_AT[7] ← 7;
03100 END "IN";
03200
03300
00100
00200
00300 PROCEDURE COR(INTEGER MODLINES,DIREC,SEARCH;
00400 REAL TOLER; REAL ARRAY CORNMOD);
00500 BEGIN "COR"
00600
00700 SHORT INTEGER WSEARCH;
00800
00900
01000
01100 SHORT INTEGER ARRAY WIND[0:X_WIDTH,0:Y_WIDTH];
01200 ⊃ Array WIND is declared in an inner procedure so that
01300 X_WIDTH and Y_WIDTH can be selected at run time;
01400
01500
01600 SHORT REAL ARRAY EDGES[1:EDGE_LIMIT],
01700 HUMPS[0:LINE_LIMIT,1:HUMP_LIMIT], VERTEX[1:VERT_LIMIT,1:10];
01800 SHORT REAL ARRAY INTER[1:2,1:5],LIN[1:3,1:5],FOLLOW[1:6];
01900
02000
02100 REQUIRE "EDGED.HDR[VIS,WAP]" SOURCE_FILE;
02200 REQUIRE "LINE.HDR[VIS,WAP]" SOURCE_FILE;
02300
02400
02500
02600
02700 SIMPLE PROCEDURE HISTO;
02800 BEGIN "HISTO"
02900 SHORT INTEGER I,X,Y;
03000
03100 ⊃ Compute the histogram;
03200 FOR I←0 STEP 1 UNTIL 15 DO HIST[I]←0;
03300 FOR X←0 STEP 1 UNTIL LOOK_AT[4]-1 DO
03400 FOR Y←0 STEP 1 UNTIL LOOK_AT[5] DO
03500 BEGIN
03600 I←WIND[X,Y];
03700 HIST[I]←HIST[I]+1;
03800 END;
03900
04000 ⊃ Find boundary levels;
04100 I←0; WHILE (HIST[I]=0)∧(I<15) DO I←I+1; MINI←I;
04200 I←15; WHILE (HIST[I]=0)∧(I>0) DO I←I-1; MAXI←I;
04300 LOOK_AT[6]←(15-MAXI) DIV 2;
04400 LOOK_AT[7]←(15-MINI) DIV 2;
04500 END "HISTO";
04600
04700
04800
04900
05000 PROCEDURE SLICE;
05100 ⊃ Here we check the intensity distribution in the window;
05200 BEGIN "SLICE"
05300 SHORT INTEGER ARRAY HIST1[0:15];
05400 SHORT INTEGER I,J,BAR,MAX;
05500
05600 HISTO;
05700 IF LOOK_AT[6]=LOOK_AT[7] THEN
05800 BEGIN
05900 OUTSTR("SLICE-FAILED:
06000 UNIFORM INTENSITY IN WINDOW (CLIPS="&
06100 CVS(LOOK_AT[6])&")"ACRLF);
06200 EXFLAG←10; RETURN;
06300 END;
06400 END "SLICE";
06500
06600
06700
06800
06900 SIMPLE PROCEDURE SETWIND;
07000
07100 ⊃ This procedure is used for disk pictures only.
07200 Array WIND stores the intensity values;
07300
07400 BEGIN
07600 SHORT INTEGER X,Y,XP,YP,FACTOR;
07700 DEFINE XMIN ="LOOK_AT[2] - (LOOK_AT[4] DIV 2) -LSIDE",
07800 YMIN = "LOOK_AT[3] - (LOOK_AT[5] DIV 2) - FLINE";
07900 IF BITS≤4 THEN FACTOR←1 ELSE FACTOR←4;
08000 IF DEB_EYE∨WSEARCH≥1 THEN
08100 BEGIN
08200 OUTSTR("WINDOW CENTER AT "&CVS(LOOK_AT[2])&" "&CVS(LOOK_AT[3])ACRLF);
08300 INCHWL;
08400 END;
08500
08600 FOR X←0 STEP 1 UNTIL LOOK_AT[4] DO
08700 FOR Y←0 STEP 1 UNTIL LOOK_AT[5] DO
08800 BEGIN
08900 XP ← X + XMIN;
09000 YP ← Y + YMIN;
09100 WIND[X,Y] ← GETPNT(XP,YP) DIV FACTOR;
09200 END;
09300 END;
09400
09500
09600
00100
00200 SIMPLE PROCEDURE DISPLAY;
00300 ⊃ Display the array of intensity numbers in the window;
00400
00500 BEGIN "DISPLAY"
00600 SHORT INTEGER X,Y, SCALE, XBOUND,YBOUND;
00700 SHORT REAL NUMB,DEL, DELX,DELY, MINSCAL;
00800 SHORT INTEGER X1,Y1,X2,Y2;
01000 X1←LOOK_AT[2]-(LOOK_AT[4] DIV 2);
01100 X2←LOOK_AT[2]+(LOOK_AT[4] DIV 2);
01200 Y1←LOOK_AT[3]-(LOOK_AT[5] DIV 2);
01300 Y2←LOOK_AT[3]+(LOOK_AT[5] DIV 2);
01400 INIT_DOMAIN(X1,Y2,X2,Y1); ⊃ Set scale for display;
01500 MINSCAL←SMALLER(LOOK_AT[4],LOOK_AT[5]);
01600 SCALE←(MINSCAL DIV 25)+1;
01700 XBOUND←TX(X1);
01800 YBOUND←TY(Y1);
01900 DELX←TX(X2)-XBOUND;
02000 DELY←TY(Y2)-YBOUND;
02100 NUMB←MINSCAL;
02200 ⊃ OUTSTR(" IN DISPLAY-- NUMBER="&CVG(NUMB)ACRLF);
02300 ⊃ OUTSTR(" XBOUND="&CVS(XBOUND)&" YBOUND="&CVS(YBOUND)ACRLF);
02400 DEL←ABS(SMALLER(DELX,DELY))/(NUMB+1);
02500 XBOUND←XBOUND+15;
02600 YBOUND←YBOUND-25;
02700
02800 DPYTYP(-200,12,1); DPYSET(DPYBUF);
02900 DPYBRT(5); DPYBIG(2);
03000 BOUNDARY(X1,Y2,X2,Y1);
03100 IF DEB_EYE THEN
03200 BEGIN
03300 AIVECT(-500,0); RVECT(0,320);
03400 FOR X←0 STEP 1 UNTIL 16 DO
03500 BEGIN RVECT(-10,0); RIVECT(10,-20); END;
03600 FOR X←0 STEP 1 UNTIL 3 DO
03700 BEGIN AIVECT(-530,100*X); DPYSST(CVS(5*X)); END;
03800 AIVECT(-600,380); DPYSST("CLIPS");
03900 AIVECT(-500,0); RVECT(HIST[0]/(SCALE),0);
04000 FOR X←0 STEP 1 UNTIL 14 DO
04100 BEGIN RVECT(0,20); RVECT((HIST[X+1]-HIST[X])/(SCALE),0); END;
04200 RVECT(0,20); RVECT(-HIST[15]/(SCALE),0);
04300 AIVECT(-600,40*(7-LOOK_AT[7])); RVECT(60,0);
04400 AIVECT(-600,40*(8-LOOK_AT[6])); RVECT(60,0);
04500 END;
04600
04700
04800
04900 AIVECT(-200,420); DPYSST("SCALE=1:"&CVS(SCALE)); DPYBIG(2);
05000 FOR X←0 STEP SCALE UNTIL LOOK_AT[4]-1 DO
05100 FOR Y←0 STEP SCALE UNTIL LOOK_AT[5]-1 DO
05200 BEGIN
05300 AIVECT(XBOUND+DEL*X,YBOUND-DEL*Y);
05400 DPYSST(CVS(WIND[X,Y]));
05500 END;
05600 DPYOUT(1); SETFORMAT(0,7);
05700 END"DISPLAY";
00100
00200 SIMPLE PROCEDURE GETPICTURE;
00300 BEGIN
00400 SETWIND;
00500 SLICE;
00600 END;
00700
00800
00900
01000
01100 REQUIRE "IMAGE.SAI[VIS,WAP]" SOURCE_FILE;
01200
01300 WSEARCH←SEARCH;
01400
01500 SRCHIMAG(MODLINES,DIREC,SEARCH,TOLER,CORNMOD);
01600
01700
01800 END "COR";
01900
00100
00200 PROCEDURE CORNFIT;
00300 BEGIN "CORNFIT"
00400
00500 ⊃ Now the driver program;
00600
00700
00800
00900 SIMPLE PROCEDURE BOUNDARY(SHORT REAL X1,Y1,X2,Y2);
01000 BEGIN
01100 X1 ← TX(X1);
01200 Y1 ← TY(Y1);
01300 X2 ← TX(X2);
01400 Y2 ← TY(Y2);
01500 AIVECT(X1,Y1);
01600 AVECT(X1,Y2);
01700 AVECT(X2,Y2);
01800 AVECT(X2,Y1);
01900 AVECT(X1,Y1);
02000 END;
02100
02200
02300 SIMPLE PROCEDURE ARROW(REAL X,Y,DX,DY);
02400 BEGIN
02500 REAL FACTOR,X1,X2,Y1,Y2;
02600 FACTOR←1.5;
02700 DX←DX*FACTOR;
02800 DY←DY*FACTOR;
02900 X1 ← TX(X-DX);
03000 X2 ← TX(X+DX);
03100 Y2 ← TY(Y+DY);
03200 Y1 ← TY(Y-DY);
03300 AIVECT(X1,Y1);
03400 AVECT(X2,Y2);
03500 X1← TX(X+DX/2.-DY/2.);
03600 Y1← TY(Y+DY/2.+DX/2.);
03700 AIVECT(X1,Y1);
03800 AVECT(X2,Y2);
03900 Y1← TY(Y+DY/2.-DX/2.);
04000 X1← TX(X+DX/2.+DY/2.);
04100 AVECT(X1,Y1);
04200 END;
04300
04400
04500
04600 SIMPLE PROCEDURE LINE_MOD(SHORT REAL CX,CY; REFERENCE SHORT REAL
04700 THETA,COSTH,SINTH);
04800 ⊃ This procedure takes the direction cosines CX, CY and
04900 calculates the appropriate angle theta;
05000
05100 BEGIN
05200 SHORT REAL PHI;
05300 IF ABS(CX) ≥.10@-8 THEN
05400 BEGIN
05500 PHI ← ATAN(CY/CX);
05600 IF CX<0 THEN PHI←PHI+PI1;
05700 END ELSE
05800 IF CY≥0 THEN PHI ← PIO2 ELSE PHI ← -PIO2;
05900 THETA ← PHI +PI1;
06000 COSTH←COS(THETA);
06100 SINTH←SIN(THETA);
06200 IF DEB_EYE THEN OUTSTR(CRLF&"PHI = " &CVG(PHI)
06300 &"THETA = " &CVG(THETA)
06400 &" SINTH="&CVG(SINTH)
06500 &" COSTH="&CVG(COSTH)&CRLF);
06600 END;
06700
06800
06900
07000 PROCEDURE DISP_MODEL(SHORT INTEGER N,DIREC; SHORT REAL XCM,YCM;
07100 SHORT REAL ARRAY CORNMOD);
07200
07300 ⊃ Here we calculate and display the model of a line or corner;
07400
07500 BEGIN "MOD"
07600
07700
07800 REAL PROCEDURE SMALLER(REAL L1,L2);
07900 IF L1<L2 THEN RETURN(L1) ELSE RETURN(L2);
08000
08100 SHORT REAL XC,YC, DX,DY,DPX,DPY,TXC,TYC,
08200 DX3,DY3, L,LO2;
08300 LABEL AFTER;
08400 ⊃ DISPLAY MODEL OF LINE OR CORNER;
08500 ⊃ OUTSTR(" DIREC="&CVS(DIREC)ACRLF);
08600 L←SMALLER(15.,SQRT(X_WIDTH*Y_WIDTH)/2.);
08700 LO2←L/2.;
08800 DPX←CORNMOD[1,COSTHETA]; DPY←CORNMOD[1,SINTHETA];
08900 DY←CORNMOD[1,COSDIR]; DX←CORNMOD[1,SINDIR];
09000 XC←XCM-LO2*DX; YC←YCM-LO2*DY;
09100 IF N=1 THEN
09200 BEGIN
09300 AIVECT(TX(XC),TY(YC));
09400 AVECT(TX(XCM+LO2*DX),TY(YCM+LO2*DY));
09500 XC←XCM; YC←YCM;
09600 END ELSE
09700 BEGIN
09800 TXC←TX(XCM); TYC←TY(YCM);
09900 AIVECT(TX(XCM-L*DX),TY(YCM-L*DY));
10000 AVECT(TXC,TYC);
10100 END;
10200 ARROW(XC,YC,DPX,DPY);
10300 IF DIREC=0 THEN ARROW(XC,YC,-DPX,-DPY);
10400 IF N=1 THEN GO TO AFTER;
10500 ⊃ IF ABS(DPY)>0.5 THEN ARROW(XC,YC-3,DX,DY)
10600 ELSE ARROW(XC-3,YC,DX,DY);
10700 IF N=2 THEN
10800 BEGIN
10900 AIVECT(TXC,TYC);
11000 DX←CORNMOD[2,SINDIR]; DY←CORNMOD[2,COSDIR];
11100 DPX←CORNMOD[2,COSTHETA];
11200 DPY←CORNMOD[2,SINTHETA];
11300 XC←XCM-LO2*DX; YC←YCM-LO2*DY;
11400 AVECT(TX(XCM-L*DX),TY(YCM-L*DY));
11500 ARROW(XC,YC,DPX,DPY);
11600 IF DIREC=0 THEN ARROW(XC,YC,-DPX,-DPY);
11700 ⊃ IF ABS(DPY)>0.5 THEN
11800 ARROW(XC,YC-3,DX,DY)
11900 ELSE ARROW(XC-3,YC,DX,DY);
12000 GO TO AFTER;
12100 END;
12200 DX←CORNMOD[2,SINDIR]; DY←CORNMOD[2,COSDIR];
12300 AIVECT(TX(XCM-L*DX),TY(YCM-L*DY));
12400 AVECT(TXC,TYC);
12500 DX3←CORNMOD[3,SINDIR]; DY3←CORNMOD[3,COSDIR];
12600 AVECT(TX(XCM-L*DX3),TY(YCM-L*DY3));
12700 DPX←CORNMOD[2,COSTHETA]; DPY←CORNMOD[2,SINTHETA];
12800 XC←XCM-LO2*DX; YC←YCM-LO2*DY;
12900 ⊃ IF ABS(DPY)>0.5 THEN ARROW(XC,YC-3,DX,DY)
13000 ELSE ARROW(XC-3,YC,DX,DY);
13100 DPX←CORNMOD[3,COSTHETA]; DPY←CORNMOD[3,SINTHETA];
13200 XC←XCM-LO2*DX3; YC←YCM-LO2*DY3;
13300 ARROW(XC,YC,DPX,DPY);
13400 IF DIREC=0 THEN ARROW(XC,YC,-DPX,-DPY);
13500 ⊃ IF ABS(DPY)>0.5 THEN ARROW(XC,YC-3,DX3,DY3)
13600 ELSE ARROW(XC-3,YC,DX3,DY3);
13700 AFTER: DPYBIG(3);
13800 AIVECT(-300,420);
13900 DPYSST("MODEL OF CORNER");
14000 AIVECT(-500,380);
14100 DPYSST("ARROWS(PERPENDICULAR TO LINES) POINT FROM LIGHT TO DARK");
14200 DPYOUT(1);
14300 END "MOD";
14400
14500
00100
00200 DEFINE XTIME(FOO)={XCEN+10.*SIN(PI6*(FOO))};
00300 DEFINE YTIME(FOO)={YCEN-10.*COS(PI6*(FOO))};
00400 SHORT INTEGER I,DIREC, SIGD, SEARCH,J,MODLINES,SIZE;
00500 SHORT REAL XIB,YIB,XIC,YIC,XID,YID,XIE,YIE,XIBB,YIBB,XCEN,YCEN;
00600 SHORT REAL TOLER,CX,CY,CX1,CY1,XX1,YY1,XX2,YY2,TIME1,TIME2,TIME3;
00700
00800 SHORT REAL T1RAD,T2RAD,T3RAD;
00900 REAL TIME;
01000
01100 STRING INSTRING,TYPE_CORN;
01200 SHORT REAL ARRAY CORNMOD[1:3,8:13];
01300 LABEL LOOP,LOOP2,PAR,PARMS,NEWPIC,SETSIG,WIN;
01400 COMMENT LABELS MUST BE DECLARED BEFORE USE -- IN FACT, THEY HAVE
01500 TO BE DECLARED WITHIN THE INNER-MOST BLOCK IN WHICH THE
01600 STATEMENT BEING LABELED APPEARS. (SEE SAIL 3.4);
01700
01800
01900
02000 INTEGER PROCEDURE LARGER(SHORT INTEGER L1,L2);
02100 IF L1>L2 THEN RETURN(L1) ELSE RETURN(L2);
02200
02300
02400 ⊃ Main Program;
02500 TVPIC ← EVERY;
02600 NEWPIC: INPUT; ⊃ THIS READS IN A PICTURE FROM THE DISK;
02700 DIS_EYE←TRUE; DEB_EYE←FALSE;
02800 OUTSTR(" ARE YOU DEBUGGING AND WANT ALL POSSIBLE OUTPUT?
02900 Y OR N? "ACRLF);
03000 IF INCHWL="Y" THEN DEB_EYE←TRUE;
03100
03200 OUTSTR(" DO YOU WANT CALCOMP PLOTS? Y OR N?"ACRLF);
03300 IF INCHWL≠"Y" THEN CAL_COMP←0 ELSE
03325 BEGIN
03350 CAL_COMP←-1;
03375 OUTSTR(CRLF&" STARTING CORNER NUMBER FOLLOWED BY <CR> ");
03385 CORNERNUMBER←CVD(INCHWL);
03395 END;
03400
03500 WIN: OUTSTR(" THE STANDARD OR PRESENT WINDOW SIZE IS:
03600 WIDTH="&CVS(X_WIDTH)&" HEIGHT="&CVS(Y_WIDTH)&
03700 " DO YOU WANT TO CHANGE IT? Y OR N? "ACRLF);
03800 IF INCHWL="Y" THEN
03900 BEGIN
04000 OUTSTR(" WIDTH AND HEIGHT
04100 EACH FOLLOWED BY A CARRIAGE-RETURN "ACRLF);
04200 X_WIDTH←CVD(INCHWL);
04300 Y_WIDTH←CVD(INCHWL);
04400 DELTA_X←X_WIDTH/2.-6;
04500 DELTA_Y←Y_WIDTH/2.-6;
04600 IF SEARCH≥1 THEN
04700 BEGIN
04800 DELTA_X←DELTA_X+4;
04900 DELTA_Y←DELTA_Y+4;
05000 END;
05100 SIZE←X_WIDTH*Y_WIDTH;
05200 EDGE_LIMIT←LARGER(1200,SIZE);
05300 LT_LIMIT←LARGER(600,SIZE/4);
05400 LINE_LIMIT←LARGER(15,SIZE/80);
05500 VERT_LIMIT←LINE_LIMIT;
05600 GO TO WIN;
05700 END;
05800
05900
06000 LOOP: OUTSTR(" ARE YOU LOOKING FOR A LINE,SIMPLE CORNER(2 SIDES),
06100 OR PHYSICAL CORNER(3 SIDES)? [TYPE L,C, OR P] "ACRLF);
06200
06300 MODLINES←0;
06400 TYPE_CORN←INCHWL;
06500 IF TYPE_CORN="L" THEN
06600 BEGIN
06700 MODLINES←1;
06800 OUTSTR(" ONE LINE WITH 3 NUMBERS, THE FIRST TWO
06900 DESIGNATE THE CENTER OF THE LINE IN SCREEN COORDINATES,
07000 THE THIRD IS THE VALUE OF THE HOUR HAND WHEN IT IS PARALLEL TO THE
07100 LINE WHILE THE FORTH IS ANY HOUR-HAND SETTING ON THE SIDE OF THE
07200 OBJECT."ACRLF);
07300 END;
07400 IF TYPE_CORN="C" THEN
07500 BEGIN
07600 MODLINES←2;
07700 OUTSTR(" ONE LINE WITH 4 NUMBERS THE FIRST TWO
07800 DESIGNATES THE VERTEX IN SCREEN COORDINATES WHILE THE OTHERS GIVE
07900 THE ANGLES OF THE LINES IN HOUR-HAND VALUES IN A CLOCKWISE MANNER
08000 ABOUT THE VERTEX."ACRLF);
08100 END;
08200 IF TYPE_CORN="P" THEN
08300 BEGIN
08400 MODLINES←3;
08500 OUTSTR(" ONE LINE WITH 5 NUMBERS THE FIRST TWO
08600 DESIGNATES THE VERTEX IN SCREEN COORDINATES WHILE THE OTHERS GIVE
08700 THE ANGLES OF THE LINES IN HOUR-HAND VALUES IN A CLOCKWISE MANNER
08800 ABOUT THE VERTEX."ACRLF);
08900 END;
09000 IF MODLINES=0 THEN GO TO LOOP;
09100
09200
09300 INSTRING ← INCHWL;
09400 XIB ← REALSCAN(INSTRING,DUMMY);
09500 YIB ← REALSCAN(INSTRING,DUMMY);
09600 TIME1 ← REALSCAN(INSTRING,DUMMY);
09700 TIME2 ← REALSCAN(INSTRING,DUMMY);
09800 TIME3 ← REALSCAN(INSTRING,DUMMY);
09900
10000
10100 PARMS: NLINES←NVERTEX←NCORNERS←0;
10200
10300 OUTSTR(" ONE LINE WITH 3 WAL PARAMETERS.
10400 FIRST IS INTENSITY:
10500 -1 FOR DARKER OUTSIDE
10600 0 FOR UNKNOWN
10700 1 FOR LIGHTER OUTSIDE
10800 SECOND IS SEARCH:
10900 -1 FOR USE WINDOW ONLY
11000 N≥1 FOR SEARCH IN AN AREA OF DIMENSION
11100 N(INTEGER) ABOUT INITIAL WINDOW
11200 THIRD IS TOLERANCE OF ANGLE MATCH:
11300 USUALLY 0.1 BUT DOWN TO 0.02 WITH CARE.
11400 IF TOLERANCE IS >1 THEN ANY CORNER
11500 WILL BE ACCEPTED."ACRLF);
11600
11700
11800 INSTRING←INCHWL;
11900 DIREC←REALSCAN(INSTRING,DUMMY);
12000 SEARCH←REALSCAN(INSTRING,DUMMY);
12100 TOLER←REALSCAN(INSTRING,DUMMY);
12200
12300 IF TOLER>1 THEN DIREC←0;
12400 SETSIG: IF DIREC=0 THEN SIGD←1 ELSE SIGD←DIREC;
12500 XCEN←XIB; YCEN←YIB;
12600
12700
12800 IF TYPE_CORN="L" THEN
12900 BEGIN
13000 XIBB←XTIME(TIME1+6.);
13100 YIBB←YTIME(TIME1+6.);
13200 XIC←XTIME(TIME1);
13300 YIC←YTIME(TIME1);
13400 YID←YTIME(TIME2);
13500 XID←XTIME(TIME2);
13600 IF XIC*XIC+YIC*YIC≥XIBB*XIBB+YIBB*YIBB THEN
13700 BEGIN
13800 X2←XIC; X1←XIBB;
13900 Y2←YIC; Y1←YIBB;
14000 END ELSE
14100 BEGIN
14200 X1←XIC; X2←XIBB;
14300 Y1←YIC; Y2←YIBB;
14400 END;
14500 CX1←Y1-Y2; CY1←X2-X1;
14600 XX1←XCEN+CX1; YY1←YCEN+CY1;
14700 XX2←XCEN-CX1; YY2←YCEN-CY1;
14800 IF(XX1-XID)↑2+(YY1-YID)↑2≥(XX2-XID)↑2+(YY2-YID)↑2 THEN
14900 BEGIN CX←CX1; CY←CY1; END
15000 ELSE BEGIN CX←-CX1; CY←-CY1; END;
15100 CX←CX*SIGD; CY←CY*SIGD;
15200 LINE_MOD(CX,CY,CORNMOD[1,8],CORNMOD[1,COSTHETA],CORNMOD[1,SINTHETA]);
15300 CORNMOD[1,11]←-SIGD;
15400 CORNMOD[1,SINDIR]←CORNMOD[1,11]*CORNMOD[1,SINTHETA];
15500 CORNMOD[1,COSDIR]←-CORNMOD[1,11]*CORNMOD[1,COSTHETA];
15600 GO TO LOOP2;
15700 END;
15800 IF TYPE_CORN="C" THEN
15900 BEGIN
16000 XIC←XTIME(TIME1);
16100 YIC←YTIME(TIME1);
16200 YID←YTIME(TIME2);
16300 XID←XTIME(TIME2);
16400 CX←(YIC-YIB)*SIGD;
16500 CY←(XIB-XIC)*SIGD;
16600 LINE_MOD(CX,CY,CORNMOD[1,8],CORNMOD[1,COSTHETA],CORNMOD[1,SINTHETA]);
16700 CX←(YIB-YID)*SIGD;
16800 CY←(XID-XIB)*SIGD;
16900 LINE_MOD(CX,CY,CORNMOD[2,8],CORNMOD[2,COSTHETA],CORNMOD[2,SINTHETA]);
17000 CORNMOD[1,11]←-SIGD; CORNMOD[2,11]←SIGD;
17100 FOR J←1 STEP 1 UNTIL MODLINES DO
17200 BEGIN
17300 CORNMOD[J,SINDIR]←CORNMOD[J,11]*CORNMOD[J,SINTHETA];
17400 CORNMOD[J,COSDIR]←-CORNMOD[J,11]*CORNMOD[J,COSTHETA];
17500 END;
17600 GO TO LOOP2;
17700 END;
17800 IF TYPE_CORN="P" THEN
17900 BEGIN
18000 XIC←XTIME(TIME1);
18100 YIC←YTIME(TIME1);
18200 YID←YTIME(TIME2);
18300 XID←XTIME(TIME2);
18400 XIE←XTIME(TIME3);
18500 YIE←YTIME(TIME3);
18600 CX←(YIC-YIB)*SIGD;
18700 CY←(XIB-XIC)*SIGD;
18800 LINE_MOD(CX,CY,CORNMOD[1,8],CORNMOD[1,COSTHETA],CORNMOD[1,SINTHETA]);
18900 CX←(YIB-YID)*SIGD;
19000 CY←(XID-XIB)*SIGD;
19100 LINE_MOD(CX,CY,CORNMOD[2,8],CORNMOD[2,COSTHETA],CORNMOD[2,SINTHETA]);
19200 CX←(YIB-YIE)*SIGD;
19300 CY←(XIE-XIB)*SIGD;
19400 LINE_MOD(CX,CY,CORNMOD[3,8],CORNMOD[3,COSTHETA],CORNMOD[3,SINTHETA]);
19500 CORNMOD[1,11]←-SIGD; CORNMOD[2,11]←CORNMOD[3,11]←SIGD;
19600 FOR J←1 STEP 1 UNTIL MODLINES DO
19700 BEGIN
19800 CORNMOD[J,SINDIR]←CORNMOD[J,11]*CORNMOD[J,SINTHETA];
19900 CORNMOD[J,COSDIR]←-CORNMOD[J,11]*CORNMOD[J,COSTHETA];
20000 END;
20100 END;
20200
20300
20400 LOOP2: IF DEB_EYE THEN INCHWL;
20500
20600 X1←XCEN-X_WIDTH/2;
20700 X2←XCEN+X_WIDTH/2;
20800 Y2←YCEN+Y_WIDTH/2;
20900 Y1←YCEN-Y_WIDTH/2;
21000 DPYSET(BUF);
21100 INIT_DOMAIN(X1,Y2,X2,Y1);
21200 BOUNDARY(X1,Y2,X2,Y1);
21300 DISP_MODEL(MODLINES,DIREC,XCEN,YCEN,CORNMOD);
21400 IF CAL_COMP THEN CALCOMP("MODEL",BUF);
21500 INCHWL; INCHWL;
21600 OUTSTR(CRLF&"CENTER OF THE WINDOW "&
21700 CVG(XCEN)&" "& CVG(YCEN) ACRLF);
21800 OUTSTR(" ARE YOU SATISFIED WITH THE MODEL?
21900 Y OR N? "ACRLF);
22000 DPYCLR;
22100 IF INCHWL="N" THEN GO TO LOOP;
22110 OUTSTR( " DO YOU WANT ALL CORNERS THAT MATCH? Y OR N?"ACRLF);
22120 IF INCHWL="Y" THEN WANT_ALL←-1 ELSE WANT_ALL←0;
22200 ⊃ IF ¬DEB_EYE THEN
22300 BEGIN
22400 OUTSTR(" DO YOU WANT DISPLAYS? Y OR N? "ACRLF);
22500 ⊃ IF INCHWL="N" THEN DIS_EYE←0 ELSE DIS_EYE←-1;
22600 ⊃ END;
22700 ⊃ TIME←CALL(0,"RUNTIM")/1000.;
22800 ⊃ PRINT(TIME);
22900
22950 DIR_EYE[0,1]←0;
23000 LOOK_AT[1] ← 1;
23100 LOOK_AT[2] ← XCEN;
23200 LOOK_AT[3] ← YCEN;
23300 LOOK_AT[4] ← X_WIDTH;
23400 LOOK_AT[5] ← Y_WIDTH;
23500 CAL2_COMP←0;
23600 COR(MODLINES, DIREC, SEARCH, TOLER, CORNMOD);
23700 COMMENT THIS IS THE CALL ON THE CORNER-FINDER "WALEYE". NOTICE
23800 THAT THE FOUR PARAMETERS AND CORNMOD[...] ARE
23900 PASSED AS ARGUMENTS.;
24000
24100
24200 ⊃ TIME←CALL(0,"RUNTIM")/1000.;
24300 ⊃ PRINT(TIME);
24400 IF EXFLAG≠0∨¬DIS_EYE THEN GO TO PAR;
24500 INCHWL; INCHWL;
24600 DISP_MODEL(MODLINES,DIREC,XCEN,YCEN,CORNMOD);
24700 INCHWL; INCHWL;
24800
24900
25000
25100 PAR:
25200 OUTSTR("DO YOU WANT TO CHANGE THE THREE WAL PARAMETERS? --- Y OR N"ACRLF);
25300 COMMENT NOTICE THAT THE INPUT STRING IS ONLY COMPARED
25400 WITH "Y". IF IT IS A "Y" (OR STARTS WITH A "Y" --- CHECK
25500 THE SAIL MANUAL FOR THE DETAILS OF STRING COMPARISONS ---
25600 BASICALLY THE "=" COMPARISON ONLY COMPARES THE FIRST
25700 CHARACTERS. THERE IS A BUILT-IN FUNCTION EQUAL(...)
25800 WHICH COMPARES THE COMPLETE STRINGS.), THE JUMP TO LOOP
25900 WILL BE TAKEN. IF THE INPUT STRING IS ANYTHING ELSE
26000 (EVEN JUST A CARRIAGE-RETURN) THE JUMP WILL NOT BE TAKEN.
26100
26200 WARNING: SOMETIMES THE OUTPUT MESSAGES (LIKE THE ONE
26300 PRODUCED BY THE STATEMENT ABOVE) ARE INTERSPERSED WITH
26400 THE HAND/EYE TRACING INFORMATION. IF EVERYTHING COMES
26500 TO A HALT, LOOK THROUGH THE LAST FEW LINES OF THE TRACE
26600 OUTPUT TO SEE IF ONE OF THE PROGRAM-PRODUCED QUESTIONS
26700 OR REMARKS IS EMBEDDED THERE.;
26800
26900 IF INCHWL="Y" THEN GO TO PARMS;
27000 OUTSTR("DO YOU WANT TO CHANGE THE MODEL? --- Y OR N"ACRLF);
27100 IF INCHWL="Y" THEN GO TO LOOP;
27200 OUTSTR(" DO YOU WANT A NEW INPUT FILE? --- Y OR N "ACRLF);
27300 IF INCHWL≠"N" THEN GO TO NEWPIC;
27400
27500 END "CORNFIT";
27600
27700 CORNFIT;
27800
27900
28000 END "WALEYE";